package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.common.CommonData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterEventData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterStatisticData;
import com.navinfo.tripanalysis.common.arithmetic.common.VarStatus;
import com.navinfo.tripanalysis.common.arithmetic.convert.EventDataConvert;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarSpeedOver_0200;
import com.navinfo.tripanalysis.common.arithmetic.enums.EventType;
import com.navinfo.tripanalysis.common.arithmetic.exception.RangeAssert;
import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.config.ConfigMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 实时计算：单独0200算法链的超速算法<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：事件<br/>
 * @author CAI.HS
 */
public class SpeedOver_0200 extends AbstractArithmetic<VarSpeedOver_0200> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.speedOver_0200;
    /**
     * 超速阀值，单位km/h
     */
    private int speedThreshold = ConfigMap.getInteger("0200_SpeedOver_Speed");
    /**
     * 超速时长阀值，单位ms
     */
    private long timeThreshold = ConfigMap.getLong("0200_SpeedOver_Time");

    @Override
    public void calculate() {
        logger.debug("进入0200算法链的超速算法.[terminalId:{}]", terminalId);
        VarSpeedOver_0200 var = getObj();
        CommonData commonData = getCommonData();

        //1、判断速度合法性
        RangeAssert.speedKmhIsInTheRange(commonData.getSpeedKmh());

        //2、将默认组加到map中
        Map<Integer, Integer> teamPair = new HashMap<>();
        teamPair.put(0, speedThreshold);

        // 判断超速
        for (Map.Entry<Integer, Integer> entry : teamPair.entrySet()) {
            Integer teamId = entry.getKey();//组ID
            Integer value = entry.getValue();//组ID对应的超速阀值

            VarStatus teamData = var.getDataMap().getOrDefault(teamId.toString(), new VarStatus());
            boolean preStatus = teamData.isPreStatus();
            boolean curStatus = commonData.getSpeedKmh() > value;
            teamData.setPreStatus(curStatus);

            var.getDataMap().put(teamId.toString(), teamData);
            logger.debug("0200超速算法，超速状态：teamId:{},preStatus:{},curStatus:{}.[terminalId:{}]", teamId.toString(), preStatus, curStatus, terminalId);

            //算法计算
            switch (super.getEventStatus(preStatus, curStatus)) {
                case START:
                    logger.debug("0200超速算法，事件开始.[terminalId:{}, team:{}]", terminalId,teamId);
                    OuterEventData eventData = EventDataConvert.newInstanceAndConvertStart(drivingData);
                    eventData.setEvent(EVENT_TYPE);
                    eventData.setTeamId(teamId);
                    //流计中，当前为了不推送，暂时将状态设置成S_STATUS_FINISHED
                    eventData.setStatus(OuterEventData.S_STATUS_FINISHED);
                    drivingData.putEventMultiChild(EVENT_TYPE, teamId.toString(), eventData);
                    break;
                case IN:
                    logger.debug("0200超速算法，事件中.[terminalId:{}, team:{}]", terminalId,teamId);
                    calcEventData(teamId.toString());
                    break;
                case END:
                    logger.debug("0200超速算法，事件结束.[terminalId:{}, team:{}]", terminalId,teamId);
                    calcEventData(teamId.toString());
                    endEvent(teamId.toString());
                    break;
                default:
                    logger.debug("0200超速算法，超速状态：上一次和本次都未超速，跳出算法.[terminalId:{}, team:{}]", terminalId,teamId);
            }
        }

        logger.debug("0200超速算法结束.[terminalId:{}]", terminalId);
    }


    /**
     * 累加事件数据
     * @param teamId,车队ID
     */
    private void calcEventData(String teamId) {
        Optional.ofNullable(drivingData.getEventMultiChild(EVENT_TYPE, teamId)).ifPresent(eventData ->{
            //累加里程、油耗、时长
            EventDataConvert.convertCommonExtendField(eventData, drivingData);
            eventData.setExtendField03(Optional.ofNullable(eventData.getExtendField03()).orElse(0) + getCommonData().getDffTime());
            logger.debug("0200超速 车队：{},时长：{}，阈值：{}", eventData.getTeamId(),  eventData.getExtendField03(), timeThreshold);

            if (eventData.getStatus()==OuterEventData.S_STATUS_FINISHED && eventData.getExtendField03() >= timeThreshold) {
                // 满足时长阈值后，需要推送事件开始，将状态设置成0
                eventData.setStatus(0);
            }
        });
    }

    /**
     * 结束事件
     * @param teamId,车队ID
     */
    private void endEvent(String teamId) {
        Optional.ofNullable(drivingData.getEventMultiChild(EVENT_TYPE, teamId)).ifPresent(eventData ->{
            EventDataConvert.convertEnd(eventData, drivingData);

            // 持续时长 > 时长阈值
            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) >= timeThreshold) {
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("0200超速时间{}ms,小于阈值{}ms，不进行统计", eventData.getDuration(), timeThreshold);
            }

            drivingData.removeEventMultiChild(EVENT_TYPE, teamId);
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
    }
}
